package com.tanjie.blackbean.web;

import com.tanjie.blackbean.core.auth.PermissionValidator;
import com.tanjie.blackbean.pojo.properties.BlackbeanAuthProperties;
import com.tanjie.blackbean.web.advice.ExceptionHandleAdvice;
import com.tanjie.blackbean.web.advice.WrapResponseAdvice;
import com.tanjie.blackbean.web.log.PrintLogAspect;
import com.tanjie.blackbean.web.auth.AuthInterceptor;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

/**
 * @author: tanjie
 * @date: 2022-04-02
 **/
@Slf4j
@Configuration
@AutoConfigureBefore(value = {ErrorMvcAutoConfiguration.class})
@EnableConfigurationProperties(value = {BlackbeanAuthProperties.class})
@ComponentScan(value = {"com.tanjie.blackbean.web.component", "com.tanjie.blackbean.web.auth"})
public class BlackBeanWebAutoConfiguration implements WebMvcConfigurer {

    @Resource
    AuthInterceptor authInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // order是按照升序排列的，越小越优先
        registry.addInterceptor(authInterceptor).addPathPatterns("/**").order(1);
    }

    @AutoConfigureBefore(value = {BlackBeanWebAutoConfiguration.class})
    @Configuration
    @Order(0)
    public static class BlackbeanComponentAdapter {

        @Value("${spring.application.name}")
        String applicationName;

        @Bean
        public PrintLogAspect printLogAspect() {
            log.info("---load PrintLogAspect---");
            return new PrintLogAspect();
        }

        @Bean
        public WrapResponseAdvice responseWrapAdvice() {
            log.info("---load WrapResponseAdvice---");
            return new WrapResponseAdvice();
        }

        @Bean
        public ExceptionHandleAdvice exceptionHandleAdvice() {
            log.info("---load ExceptionHandleAdvice---");
            return new ExceptionHandleAdvice();
        }

        @Bean
        @ConditionalOnMissingBean
        public PermissionValidator permissionCheck() {
            log.info("---load PermissionValidator---");
            return (userId, requiredRoles, requiredPermissions) -> log.warn("当前服务未配置PermissionValidator的实现类");
        }

        @Bean
        @ConditionalOnMissingBean
        public OpenAPI swaggerDocket() {
            log.info("---load Swagger---");
            return new OpenAPI().info(apiInfo());
        }

        private Info apiInfo() {
            return new Info()
                    .title(applicationName + "接口文档")
                    .description("服务名称:" + applicationName)
                    .version("1.0");
        }

    }

}
